home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / pc.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  8KB  |  380 lines

  1. /* OS- and machine-dependent stuff for IBM-PC running MS-DOS */
  2. #include <stdio.h>
  3. #ifdef __TURBOC__
  4. #include <dir.h>
  5. #include <sys/stat.h>
  6. #include <string.h>
  7. #include <process.h>
  8. #include <fcntl.h>
  9. #else
  10. #include <sgtty.h>
  11. #endif
  12. #include "config.h"
  13. #include "global.h"
  14. #include "mbuf.h"
  15. #include "internet.h"
  16. #include "iface.h"
  17. #include "cmdparse.h"
  18.  
  19. void    _Cdecl    __int__        (int interruptnum);
  20.  
  21. #ifdef TRACE
  22. extern FILE *trfp;            /* trace file pointer */
  23. extern char trname[];            /* trace file name */
  24. #endif
  25.  
  26. /* This flag is set by setirq() if IRQ 8-15 is used, indicating
  27.  * that the machine is a PC/AT with a second 8259 interrupt controller.
  28.  * If this flag is set, the interrupt return code in pcgen.asm will
  29.  * send an End of Interrupt command to the second 8259 as well as the
  30.  * first.
  31.  */
  32. char isat;
  33.  
  34. /* Interface list header */
  35. struct interface *ifaces;
  36.  
  37. #ifdef PC9801
  38. extern char escape;
  39. #endif
  40.  
  41. /* Aztec memory allocation control */
  42. int _STKLOW = 0;    /* Stack above heap */
  43. int _STKSIZ = 16384/16;    /* 16K stack -- overridden in grabcore */
  44. int _HEAPSIZ = 4096/16;    /* Isn't really used */
  45. int _STKRED = 4096;    /* Stack red zone in bytes -- this really matters */
  46.  
  47. char ttbuf[24*80];
  48. int saved_break;
  49.  
  50. /* Called at startup time to set up console I/O, memory heap */
  51. ioinit()
  52. {
  53. #ifndef __TURBOC__
  54.     struct sgttyb ttybuf;
  55. #endif
  56.     unsigned grabcore();
  57.  
  58.     /* Save these two file table entries for something more useful */
  59.     fclose(stdaux);
  60. #ifdef __TURBOC__
  61.     fclose(stdprn);
  62. #else
  63.     fclose(stdprt);
  64. #endif
  65.  
  66.     /* Interrupts use a special stack deep in data space.
  67.      * Calls to sbrk() (invoked by malloc when it needs more memory
  68.      * from the system) at interrupt time will fail because sbrk()
  69.      * will think that the stack has overwritten the heap. So
  70.      * grab all the memory we can now for the heap so that malloc
  71.      * won't have to call sbrk and alloc_mbuf() won't fail unnecessarily
  72.      * at interrupt time.
  73.      */
  74.     grabcore();
  75.  
  76. #ifdef __TURBOC__
  77.     /*_fmode = O_BINARY;*/
  78. #endif
  79.     setbuf(stdout,ttbuf);
  80.  
  81. #ifdef __TURBOC__
  82.     saved_break = getcbrk();
  83.     setcbrk(0);
  84.     ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff | 0x20);  /* put stdout in raw mode */
  85. #else
  86.     /* Put display in raw mode. Note that this breaks tab expansion,
  87.      * so you need to run NANSI.SYS or equivalent.
  88.      */
  89.     ioctl(1,TIOCGETP,&ttybuf);
  90.     ttybuf.sg_flags = RAW;
  91.     ioctl(1,TIOCSETP,&ttybuf);
  92. #endif
  93. }
  94. /* Called just before exiting to restore console state */
  95. iostop()
  96. {
  97. #ifndef __TURBOC__
  98.     struct sgttyb ttybuf;
  99. #endif
  100.  
  101.     setbuf(stdout,NULLCHAR);
  102. #ifdef __TURBOC__
  103.     setcbrk(saved_break);
  104.     ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff & ~0x20);  /* put stdout in cooked mode */
  105. #else
  106.     ioctl(1,TIOCGETP,&ttybuf);
  107.     ttybuf.sg_flags &= ~RAW;
  108.     ioctl(1,TIOCSETP,&ttybuf);
  109. #endif
  110.     while(ifaces != NULLIF){
  111.         if(ifaces->stop != NULLFP)
  112.             (*ifaces->stop)(ifaces);
  113.         ifaces = ifaces->next;
  114.     }
  115. }
  116. /* Spawn subshell */
  117. doshell(argc,argv)
  118. int argc;
  119. char *argv[];
  120. {
  121.     char *command,*getenv();
  122.     int ret;
  123.  
  124. #if defined(PLUS)
  125. /*
  126.  * set: cursor to block, attributes off, keyboard to ALT mode,
  127.  *      transmit functions off, use HP fonts
  128.  */
  129.     printf(/* "\033*dK"       cursor to block        */
  130.               "\033&d@"    /* display attributes off      */
  131.            /* "\033&k1\\"       KBD to ALT mode        */
  132.            /* "\033&s1A"       transmit functions on    */
  133.               "\033[11m");    /* use ALT fonts        */
  134. #endif
  135. #ifdef __TURBOC__
  136.  
  137. #ifdef TRACE
  138.     if (trfp != stdout)        /* trace to file? */
  139.         fclose(trfp);        /* close it during shell exec */
  140. #endif
  141.  
  142.     ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff & ~0x20);  /* put stdout in cooked mode */
  143.     if((command = getenv("COMSPEC")) == NULLCHAR)
  144.         command = "/COMMAND.COM";
  145.     ret = spawnv(P_WAIT,command,argv);
  146.  
  147.     ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff | 0x20);  /* put stdout in raw mode */
  148.     return ret;
  149. #else
  150.     struct sgttyb ttybuf,ttysav;
  151.  
  152.     ioctl(1,TIOCGETP,&ttysav);
  153.     ioctl(1,TIOCGETP,&ttybuf);
  154.     ttybuf.sg_flags &= ~RAW;
  155.     ioctl(1,TIOCSETP,&ttybuf);
  156.  
  157.     if((command = getenv("COMSPEC")) == NULLCHAR)
  158.         command = "/COMMAND.COM";
  159.     ret = fexecl(command,command,NULLCHAR);
  160.     ioctl(1,TIOCSETP,&ttysav);
  161. #ifdef TRACE
  162.     if (trfp != stdout)        /* re-open tracefile if not stdout */
  163.         if ((trfp = fopen(trname,"a+")) == NULLFILE)
  164.         trfp = stdout;
  165. #endif
  166.     if(ret == -1)
  167.         return -1;
  168.     else
  169.         return wait();
  170. #endif
  171. }
  172.  
  173. /* checks the time then ticks and updates ISS */
  174. static short clockstart =0;
  175. static unsigned clkval = 0;
  176. #if defined(NOMAD)   /* compiling for a HP-110 */
  177. /*
  178.  * returns the second value of the clock
  179.  */
  180. int clksec()
  181. {
  182.     _AH=0x2c;
  183.     __int__(0x21);
  184.     _AL=_DH;
  185.     _AH=0;
  186. }
  187.  
  188. void
  189. check_time()
  190. {
  191.     int32 iss();
  192.     if(clkval != clksec()) {
  193.         clkval = clksec();
  194.         icmpclk();
  195.         tick();
  196.         (void)iss();
  197.     }
  198. }
  199. #else
  200. void
  201. check_time()
  202. {
  203.     int32 iss();
  204.     short ntime;
  205.  
  206.     if(!clockstart){
  207.         /* Executed only once */
  208. #if defined(PLUS)   /* compiling for a HP-110+  */
  209.         clkval = peek(0,0x472);
  210. #else
  211.         clkval = peekw(0x6c,0x40);
  212. #endif
  213.         clockstart = 1;
  214.         return;
  215.     }
  216.     /* Read the low order word of the BIOS tick counter directly. The
  217.      * INT 1Ah call isn't used because it stupidly clears the
  218.      * "midnight passed" flag and we'd have to update the date ourselves.
  219.      * (See Norton, p222).
  220.      * 
  221.       * The PC's time-of-day handling is a real crock of shit. Why not a
  222.      * nice simple long binary count from a fixed UTC epoch, as in UNIX??
  223.      */
  224. #if defined(PLUS)
  225.     ntime = peek(0,0x472);
  226. #else
  227.     ntime = peekw(0x6c,0x40);
  228. #endif
  229.     while(ntime != clkval){    /* Handle possibility of several missed ticks */
  230.         clkval++;
  231.         icmpclk();    /* Call this one before tick */
  232.         tick();
  233.         (void)iss();
  234.     }
  235. }
  236. #endif
  237.  
  238. /* Read characters from the keyboard, translating them to "real" ASCII
  239.  * If none are ready, return the -1 from kbraw()
  240.  */
  241. int
  242. kbread()
  243. {
  244.     int kbraw(),c;
  245.  
  246. #ifdef PC9801
  247.     if((c = kbraw()) == escape){
  248.       c = -2;
  249. #else
  250.     if((c = kbraw()) == 0){
  251.         /* Lead-in to a special char */
  252.         c = kbread();
  253.         switch(c){
  254.         case 3:        /* NULL (bizzare!) */
  255.             c = 0;
  256.             break;
  257. #if defined(PLUS)
  258.         case 66:    /* f-8 key too for HP 110 Plus */
  259. #endif
  260.         case 68:    /* F-10 key (used as command-mode escape) */
  261.             c = -2;
  262.             break;
  263.         case 83:    /* DEL key */
  264.             c = 0x7f;
  265.             break;
  266.         default:    /* Dunno what it is */
  267.             c = -1;
  268.         }
  269. #endif /* PC9801 */
  270.     }
  271. #if defined(PLUS)
  272.     if(c==27 && kbhit()) {
  273.         if((c = kbraw()) == 119) return -2;
  274.         return -1;
  275.     }
  276. #endif
  277.     return c;
  278. }
  279. #define    CTLZ    26
  280. /* Special version of aputc() (used by putchar and printf) that filters
  281.  * out nasty characters that screw up the DDOS and ANSI terminal drivers
  282.  */
  283. aputc(c,file)
  284. char c;
  285. FILE *file;
  286. {
  287.     /* Nulls get displayed as spaces by ansi.sys (wrong)
  288.      * ^Z's seem to hang the DoubleDos and DesqView screen drivers
  289.      */
  290.     if((c == '\0' || c == CTLZ) && file == stdout)
  291.         return c;
  292.     /* Do end-of-line translations */
  293.     if(c == '\n')
  294.         putc('\r',file);
  295.     return putc(c,file);
  296. }
  297. /* Reset the CPU, reboot DOS */
  298. sysreset()
  299. {
  300. }
  301.  
  302. /* Install hardware interrupt handler.
  303.  * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
  304.  * Note that bus line IRQ2 maps to IRQ9 on the AT
  305.  */
  306. setirq(irq,handler)
  307. unsigned irq;
  308. void (*handler)();
  309. {
  310.     /* Set interrupt vector */
  311.     if(irq < 8){
  312.         setvect(8+irq,handler);
  313.     } else if(irq < 16){
  314.         isat = 1;
  315.         setvect(0x70 + irq - 8,handler);
  316.     } else {
  317.         return -1;
  318.     }
  319.     return 0;
  320. }
  321. /* Return pointer to hardware interrupt handler.
  322.  * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
  323.  */
  324. void
  325. (*getirq(irq))()
  326. unsigned int irq;
  327. {
  328.     void (*getvect())();
  329.  
  330.     /* Set interrupt vector */
  331.     if(irq < 8){
  332.         return getvect(8+irq);
  333.     } else if(irq < 16){
  334.         return getvect(0x70 + irq - 8);
  335.     } else {
  336.         return NULLVFP;
  337.     }
  338. }
  339. /* Disable hardware interrupt */
  340. maskoff(irq)
  341. unsigned irq;
  342. {
  343.     if(irq < 8){
  344.         setbit(0x21,(char)(1<<irq));
  345.     } else if(irq < 16){
  346.         irq -= 8;
  347.         setbit(0xa1,(char)(1<<irq));
  348.     } else {
  349.         return -1;
  350.     }
  351.     return 0;
  352. }
  353. /* Enable hardware interrupt */
  354. maskon(irq)
  355. unsigned irq;
  356. {
  357.     if(irq < 8){
  358.         clrbit(0x21,(char)(1<<irq));
  359.     } else if(irq < 16){
  360.         irq -= 8;
  361.         clrbit(0xa1,(char)(1<<irq));
  362.     } else {
  363.         return -1;
  364.     }
  365.     return 0;
  366. }
  367. /* Return 1 if specified interrupt is enabled, 0 if not, -1 if invalid */
  368. getmask(irq)
  369. unsigned irq;
  370. {
  371.     if(irq < 8)
  372.         return (inportb(0x21) & (1 << irq)) ? 0 : 1;
  373.     else if(irq < 16){
  374.         irq -= 8;
  375.         return (inportb(0xa1) & (1 << irq)) ? 0 : 1;
  376.     } else
  377.         return -1;
  378. }
  379.  
  380.